#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include "mouse.h"
#include "paint.h"

#define FILENAME  "/dev/input/mice"

#define MOUSESIZE 16

int mouse_x;
int mouse_y;

static int fd;
static char buf[3];
static unsigned long mouse_icon_buffer[MOUSESIZE][MOUSESIZE];

static int mouse_icon[MOUSESIZE][MOUSESIZE] = {
	{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0},
	{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0},
	{2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 0, 0, 0},
	{2, 1, 1, 1, 1, 2, 0, 2, 1, 1, 1, 1, 1, 2, 0, 0},
	{2, 1, 1, 1, 2, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 0},
	{2, 1, 1, 2, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2},
	{2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 2, 0},
	{2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0},
	{2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0}
};

void open_mouse()
{
	printf("\e[?25l");
	fflush(stdout);

	mouse_x = fb_width / 2;
	mouse_y = fb_height / 2;

	if ((fd = open(FILENAME, O_RDONLY)) == -1)
	{
		fprintf(stderr, "Try 'sudo ./five'     computer vs people   \n");
		fprintf(stderr, "Try 'sudo ./five s'   people   vs computer \n");
		fprintf(stderr, "Try 'sudo ./five s s' people   vs people   \n");
		exit(1);
	}

	show_mouse();
}

void close_mouse()
{
	printf("\e[?25h");
	fflush(stdout);

	close(fd);
}

void hide_mouse()
{
	int i, j;

	for (i = 0; i < MOUSESIZE; ++i)
		for (j = 0; j < MOUSESIZE; ++j)
		{
			set_color(mouse_icon_buffer[i][j]);
			pixel(mouse_x + i, mouse_y + j);

		}
}


void show_mouse()
{
	int i, j;

	for (i = 0; i < MOUSESIZE; ++i)
		for (j = 0; j < MOUSESIZE; ++j)
		{
			if (mouse_x + i >= 0 && mouse_x + i < fb_width && mouse_y + j >= 0 && mouse_y + j < fb_height)
			{
				memcpy(&mouse_icon_buffer[i][j], fbp + (mouse_y + j) * fb_width * fb_bpp + (mouse_x + i) * fb_bpp, fb_bpp);
			}
		}

	for (i = 0; i < MOUSESIZE; ++i)
		for (j = 0; j < MOUSESIZE; ++j)
			if (mouse_icon[i][j] == 1)
			{
				set_color(BLACK);
				pixel(mouse_x + i, mouse_y + j);
			}
			else if (mouse_icon[i][j] == 2)
			{
				set_color(WHITE);
				pixel(mouse_x + i, mouse_y + j);
			}
			else;
}

void read_mouse()
{
	if (read(fd, buf, 3) < 0)
		return;

	hide_mouse();

	mouse_x += buf[1];
	mouse_x = mouse_x < 0 ? 0 : mouse_x;
	mouse_x = mouse_x > fb_width - 1 ? fb_width - 1 : mouse_x;

	mouse_y -= buf[2];
	mouse_y = mouse_y < 0 ? 0 : mouse_y;
	mouse_y = mouse_y > fb_height - 1 ? fb_height - 1 : mouse_y;

	show_mouse();
}

int mouse_clicked()
{
	return (buf[0] & 1) && buf[1] == 0 && buf[2] == 0;
}
